/**
 * Clase que implementa el parser descendente recursivo para el lenguaje SMALL
 * @author manuvarel
 *
 */
public class Ejer4e {
	private static int[] stringCod;
	private static int cToken;
	private static int pos;
	private static boolean error;
	/**
	 * Método para avanzar un caracter en la cadena.
	 */
	public static void avanzar(){
		try{
			pos++;
			cToken = stringCod[pos];
		}catch(Exception e){
			System.out.println("Error al parsear la cadena");
		}
	}
	
	/**
	 * Imprmime un mensaje de error.
	 */
	public static void error(){
		error = true;
	}

	public static void statement2(){
		switch(cToken){
			case 9 : 	statement();
						avanzar();
						statement1();
						break;
			case 2  :	statement();
						avanzar();
						statement1();
						break;
			case 4  :	statement();
						avanzar();
						statement1();
						break;
			case 1  :	statement();
						avanzar();
						statement1();
						break;
			default : 	error();
		}
	}
	
	public static void statement1(){
		switch(cToken){
			case 0 	: 	avanzar();
						statement2();
						break;
			default : 	break;			//produccion lamda
		}
	}
	
	public static void statement(){
		switch(cToken){
			case 9 : 	assignementstatement(); 
						break;
			case 2 : 	IFstatement(); 
						break;
			case 4 :	DOstatement();
						break;
			case 1 :	avanzar();
						break;
			default :	error();
		}
	}
	
	public static void IFstatement(){
		switch(cToken){
			case 2 :	avanzar();
						listguardstatement1();
						if (cToken==3){
							avanzar();
						}else{
							error();
						}break;
			default : error();
		}
	}
	
	public static void DOstatement(){
		switch (cToken){
			case 4 : 	avanzar();
						listguardstatement1();
						if (cToken==4){
							avanzar();
						}else{
							error();
						}break;
			default: error();
		}
	}
	public static void listguardstatement1(){
		switch (cToken){
			case 7 : 	guardstatement();
						avanzar();
						listguardstatement();
						break;
			default : error();
		}
	}
	public static void listguardstatement(){
		switch (cToken){
			case 5 : 	avanzar();
						listguardstatement1();
						break;
			default : break;				//retorna por produccion lamda
		}
	}
	
	public static void guardstatement(){
		switch (cToken){
			case 7 :	guard();
						if (cToken==6){
							avanzar();
						}else
							error();
						if (cToken==9 || cToken==2 || cToken==4 || cToken==1){
							statement2();
						}else
							error();
						break;
			default : error();
		}
	}
	
	public static void guard(){
		switch (cToken){
			case 7 : 	avanzar();
						break;
			default : error();
		}
	}	
	
	public static void assignementstatement(){
		switch (cToken){
			case 9 : 	namelist();
						if (cToken==8){
							avanzar();
						}else{
							error();
						}
						if (cToken==11 || cToken==12){
							exprlist();
						}else {
							error();
						}break;
			case 10 :	namelist();
						if (cToken==8){
							avanzar();
						}else{
							error();
						}
						if (cToken==11 || cToken==12){
							exprlist();
						}else {
							error();
						}break;
			default :	error();
		}
	}
	
	public static void namelist(){
		switch (cToken){
			case 9 : 	avanzar();
						break;
			case 10 : 	avanzar();
						namelist();
			default : 	error();
		}
	}
	
	public static void exprlist(){
		switch (cToken){
			case 11 : 	avanzar();
						break;
			case 12 :	avanzar();
						exprlist();
						break;
			default : 	error();
		}
	}
	
	public static void main(String[] args){
		pos = 0;
		stringCod = new int[args.length + 1];
		stringCod = Codifica.small(args);
		if (stringCod.length>0){
			error = false;
			cToken = stringCod[pos];
			statement2();
			if (error){
				System.out.println("CADENA NO RECONOCIDA");
			}else{
				System.out.println("CADENA RECONOCIDA");
			}
		}
		else{
			System.out.println("CADENA NO RECONOCIDA");
		}
	}
}
